devcontainerでDocker in Docker環境を構築しCodespacesからhttps転送する
構成要素
ファイル構成
code:text
.devcontainer/devcontainer.json
.devcontainer/Dockerfile
.devcontainer/library-scripts/common-debian.sh
.devcontainer/library-scripts/docker-in-docker-debian.sh
.devcontainer/library-scripts/node-debian.sh
.devcontainer/library-scripts/python-debian.sh
docker-compose.yml
Makefile
backend/
frontend/
nginx/
コード
WIP: 実際に動くものを公開用に作り中
devcontainer.json を以下の2つを元に作成
code:.devcontainer/devcontainer.json
{
"name": "Docker in Docker",
"build": {
"dockerfile": "Dockerfile",
"args": {
"PYTHON_VERSION": "3.9",
"NODE_VERSION": "14"
}
},
"overrideCommand": false,
// Set *default* container specific settings.json values on container create.
"settings": {
"python.pythonPath": "/usr/local/bin/python",
"python.languageServer": "Pylance",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-azuretools.vscode-docker",
"ms-python.python",
"ms-python.vscode-pylance",
"ecmel.vscode-html-css",
"esbenp.prettier-vscode",
"eamodio.gitlens",
"ms-vscode.vscode-typescript-next",
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"portsAttributes": {
"443": {
"label": "HTTPS",
},
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "docker-compose build && docker-compose up -d",
// "remoteUser": "vscode"
}
Dockerfile を以下の2つを混ぜて作成
code:code:.devcontainer/Dockerfile
# Choice Python version: 3, 3.9, 3.8, 3.7, 3.6 ARG PYTHON_VERSION="3.9"
# moby-cli requires debian10(buster) instead of debian11(bullseye)
FROM python:${PYTHON_VERSION}-buster
ARG INSTALL_ZSH="true"
# Option Upgrade OS packages to their latest versions ARG UPGRADE_PACKAGES="false"
# Option Enable non-root Docker access in container ARG ENABLE_NONROOT_DOCKER="true"
# Option Use the OSS Moby Engine instead of the licensed Docker Engine ARG USE_MOBY="true"
# Install needed packages and setup non-root user. Use a separate RUN statement to add your
# own dependencies. A user of "automatic" attempts to reuse an user ID if one already exists.
ARG USERNAME=automatic
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Copy library scripts to execute
COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get purge -y imagemagick imagemagick-6-common \
# Install common packages, non-root user
&& bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Use Docker script from script library to set things up
RUN bash /tmp/library-scripts/docker-in-docker-debian.sh "${ENABLE_NONROOT_DOCKER}" "${USERNAME}" "${USE_MOBY}" \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Choice Node.js version: none, lts/*, 16, 14, 12, 10 ARG NODE_VERSION="none"
ENV NVM_DIR=/usr/local/share/nvm
ENV NVM_SYMLINK_CURRENT=true \
PATH=${NVM_DIR}/current/bin:${PATH}
RUN bash /tmp/library-scripts/node-debian.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}" \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Setup default python tools in a venv via pipx to avoid conflicts
ENV PIPX_HOME=/usr/local/py-utils \
PIPX_BIN_DIR=/usr/local/py-utils/bin
ENV PATH=${PATH}:${PIPX_BIN_DIR}
RUN bash /tmp/library-scripts/python-debian.sh "none" "/usr/local" "${PIPX_HOME}" "${USERNAME}" \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Remove library scripts for final image
RUN rm -rf /tmp/library-scripts
# Setting the ENTRYPOINT to docker-init.sh will start up the Docker Engine
# inside the container "overrideCommand": false is set in devcontainer.json.
# The script will also execute CMD if you need to alter startup behaviors.
# Optional If your pip requirements rarely change, uncomment this section to add them to the image. # COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp
# Optional Uncomment this section to install additional OS packages. RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends make
# Optional Uncomment this line to install global node packages. # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
その他ファイル
.devcontainer/library-scripts/common-debian.sh
.devcontainer/library-scripts/docker-in-docker-debian.sh
.devcontainer/library-scripts/node-debian.sh
.devcontainer/library-scripts/python-debian.sh
ポート転送
自動で行われる
Windowsの場合
https://scrapbox.io/files/612063b6cbe2a90021b7688f.png
このためhosts等を調整して https://任意のホスト名/ でアクセス可能
Macの場合
https://scrapbox.io/files/612064765f4477002336b1c1.png
このためhosts等を調整しても https://任意のホスト名/ でアクセスできない
https://任意のホスト名:62371/ とすれば初回アクセスは可能だがリダイレクト等が期待通りに動作しない
Macで以下のコマンドを実行
メモ(TBD要整理)
Mac上のdevcontainerではDocker設定画面でsharing folderを指定すれば動作するらしい
debian 10 + moby で構築している
python:3 だとdebian11 bullseye ベースとなり、mobyがインストールできない
python:3-buster をベースにして解決
Macで1024以下の Priviledge Ports (特権ポート)を開けない
VSCodeのroot権限での起動を検討したが、以下を読むと、止めた方が良さそう
devcontainerで4443等で開いておき、Mac上でncat等で443に転送するのがよさそう
netcat, ipfw, pf, ... どれを使うのが楽?
Windowsでは特権ポート問題がないので、443で実行できた
devcontainerやその中で使うコンテナをGitHub ActionsでGitHub Container RegistryにPUSHしておき、これを使う
できた.
TODO
devcontainerに置きたいnginxのHTTPS証明書をGitHubのSecretsに置く